#include "gtkadjustment.h"
#include "gtkgesturedrag.h"
#include "gtkeventcontrollermotion.h"
+#include "gtkdragsource.h"
/**
* SECTION:gtkcolumnview
gboolean reorderable;
gboolean in_column_resize;
+ gboolean in_column_reorder;
int drag_pos;
int drag_x;
+ int drag_offset;
+ int drag_column_x;
};
struct _GtkColumnViewClass
col_size = sizes[i].natural_size;
gtk_column_view_column_allocate (column, x, col_size);
+ if (self->in_column_reorder && i == self->drag_pos)
+ gtk_column_view_column_set_header_position (column, self->drag_x);
+
x += col_size;
}
return graphene_rect_contains_point (&rect, &(graphene_point_t) { x, y});
}
+static gboolean
+gtk_column_view_in_header (GtkColumnView *self,
+ GtkColumnViewColumn *column,
+ double x,
+ double y)
+{
+ GtkWidget *header;
+ graphene_rect_t rect;
+
+ header = gtk_column_view_column_get_header (column);
+
+ if (!gtk_widget_compute_bounds (header, self->header, &rect))
+ return FALSE;
+
+ return graphene_rect_contains_point (&rect, &(graphene_point_t) { x, y});
+}
+
static void
header_drag_begin (GtkGestureDrag *gesture,
double start_x,
{
int i, n;
+ self->drag_pos = -1;
+
n = g_list_model_get_n_items (G_LIST_MODEL (self->columns));
for (i = 0; !self->in_column_resize && i < n; i++)
{
gtk_column_view_column_get_allocation (column, NULL, &size);
gtk_column_view_column_set_fixed_width (column, size);
+
self->drag_pos = i;
self->drag_x = start_x - size;
self->in_column_resize = TRUE;
break;
}
+ if (gtk_column_view_get_reorderable (self) &&
+ gtk_column_view_in_header (self, column, start_x, start_y))
+ {
+ int pos;
+
+ gtk_column_view_column_get_allocation (column, &pos, NULL);
+
+ self->drag_pos = i;
+ self->drag_offset = start_x - pos;
+
+ g_object_unref (column);
+ break;
+ }
+
g_object_unref (column);
}
}
double offset_y,
GtkColumnView *self)
{
- self->in_column_resize = FALSE;
+ double start_x, x;
+
+ gtk_gesture_drag_get_start_point (gesture, &start_x, NULL);
+ x = start_x + offset_x;
+
+ if (self->in_column_resize)
+ {
+ self->in_column_resize = FALSE;
+ }
+ else if (self->in_column_reorder)
+ {
+ GtkColumnViewColumn *column;
+ GtkWidget *header;
+ int i;
+
+ column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
+ header = gtk_column_view_column_get_header (column);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (header), "dnd");
+
+ for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++)
+ {
+ GtkColumnViewColumn *col = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
+
+ if (gtk_column_view_column_get_visible (col))
+ {
+ int pos, size;
+
+ gtk_column_view_column_get_allocation (col, &pos, &size);
+ if (pos <= x && x <= pos + size)
+ {
+ gtk_column_view_insert_column (self, i, column);
+ g_object_unref (col);
+ break;
+ }
+ }
+
+ g_object_unref (col);
+ }
+
+ g_object_unref (column);
+
+ self->in_column_reorder = FALSE;
+ }
}
static void
g_object_unref (column);
}
+static void
+update_column_reorder (GtkColumnView *self,
+ double x)
+{
+ GtkColumnViewColumn *column;
+ int width;
+ int size;
+
+ column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
+ width = gtk_widget_get_allocated_width (GTK_WIDGET (self->header));
+ gtk_column_view_column_get_allocation (column, NULL, &size);
+
+ self->drag_x = CLAMP (x - self->drag_offset, 0, width - size);
+
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+ gtk_column_view_column_queue_resize (column);
+ g_object_unref (column);
+}
+
static void
header_drag_update (GtkGestureDrag *gesture,
double offset_x,
{
double start_x, x;
+ if (self->drag_pos == -1)
+ return;
+
+
+ if (!self->in_column_resize && !self->in_column_reorder)
+ {
+ if (gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, 0))
+ {
+ GtkColumnViewColumn *column;
+ GtkWidget *header;
+
+ column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
+ header = gtk_column_view_column_get_header (column);
+
+ gtk_widget_insert_after (header, self->header, gtk_widget_get_last_child (self->header));
+ gtk_style_context_add_class (gtk_widget_get_style_context (header), "dnd");
+
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+ self->in_column_reorder = TRUE;
+
+ g_object_unref (column);
+ }
+ }
+
gtk_gesture_drag_get_start_point (gesture, &start_x, NULL);
x = start_x + offset_x;
if (self->in_column_resize)
update_column_resize (self, x);
+ else if (self->in_column_reorder)
+ update_column_reorder (self, x);
}
static void